import configureStore from 'redux-mock-store'

import loadingMiddleware from 'middlewares/loadingMiddleware'
import 'libs/promise.finally'

jest.useFakeTimers()

const setup = () => {
  const middlewares = [loadingMiddleware]
  const mockStore = configureStore(middlewares)
  const store = mockStore({})

  return {
    store,
  }
}

it('should call next if there is no promise factory passed in', () => {
  const { store } = setup()
  const action = {
    type: 'FETCH_LIST',
    promise: null,
  }

  store.dispatch(action)

  expect(store.getActions()).toMatchObject([action])
  expect(store.getActions()).toMatchSnapshot()
})

it("shouldn't dispatch `loading` action when passing suppressLoading as true", () => {
  const { store } = setup()
  const action = {
    type: 'FETCH_LIST',
    promise: () => Promise.resolve(1),
    meta: {
      suppressLoading: true,
    },
  }

  store.dispatch(action)

  const actions = store.getActions()

  expect(actions.length).toBe(1)
  expect(actions[0].type).toBe(action.type)

  expect(actions).toMatchSnapshot()
})

it('should dispatch `loading` && `loaded` actions when passing promise factory', () => {
  const { store } = setup()
  const promise = Promise.resolve(1)
  const action = {
    type: 'FETCH_LIST',
    promise: () => promise,
  }

  store.dispatch(action)

  return promise.then(() => {
    jest.runAllTimers()

    const actions = store.getActions()

    expect(actions.length).toBe(1)
    expect(actions[0].type).toBe(action.type)
    expect(actions).toMatchSnapshot()
  })
})

it('should only dispatch one pair of `loading` && `loaded` actions when dispatching multiple actions simultaneous', () => {
  const { store } = setup()
  const promise1 = Promise.resolve(1)
  const promise2 = Promise.resolve(2)
  const action1 = {
    type: 'FETCH_LIST',
    promise: () => promise1,
  }
  const action2 = {
    type: 'FETCH_LIST',
    promise: () => promise2,
  }

  store.dispatch(action1)
  store.dispatch(action2)

  return Promise.all([promise1, promise2]).then(() => {
    jest.runAllTimers()

    const actions = store.getActions()

    expect(actions.length).toBe(2)

    expect(actions).toMatchSnapshot()
  })
})
